<template>
  <div class="app-container" style="position: relative">
    <div id="myMap" ref="map" style="width:100%;height:900px;" />
    <awc ref="awc" @addLayer="addLayer" />
    <point ref="point" />
    <div class="colors">
      <dl v-for="(item,index) in colors" :key="index" class="flex">
        <dt :style="{background:item.color}"><b>{{ item.value }}</b></dt>
      </dl>
    </div>
    <div class="tools">
      <el-dropdown split-button type="primary" class="mr12" @command="handleCommand">
        历史记录
        <el-dropdown-menu slot="dropdown">
          <el-dropdown-item v-for="(item,index) in gridPartitions" :key="index" :command="item">
            {{ item.name }}
          </el-dropdown-item>
        </el-dropdown-menu>
      </el-dropdown>
      <el-button @click="showPointDialog">单点计算</el-button>
      <el-button @click="showDialog">载入文件计算</el-button>
      <el-button color="#626aef" @click="clearKriging()">清空图层</el-button>
    </div>
  </div>
</template>

<script>
import { boundaries, google } from '@/utils/constant'
import { hotColor, average, boundariesMerge } from '@/utils'
import * as turf from '@turf/turf'
import { getVectorContour } from 'kriging-contour/dist/kriging-contour.js'
import { mapGetters } from 'vuex'
import L from 'leaflet'
import Awc from './components/awc'
import Point from './components/point'
import { getAll } from '@/api/gridType'
import { getAll as getPartitions } from '@/api/gridPartition'
export default {
  components: {
    Awc,
    Point
  },
  data() {
    return {
      map: null,
      featureLayerGroup: null,
      boundaries: turf.lineString(boundaries),
      circleLayer: null,
      show: false,
      steps: [],
      colors: [],
      levelV: [],
      gridTypeId: null,
      gridPartitions: []
    }
  },
  computed: {
    ...mapGetters(['project', 'fields']),
    field() {
      const idx = this.fields.findIndex((val) => {
        return +val.project_id === this.project.id
      })
      return this.fields[idx]
    },
    circlePolygon() {
      const center = [this.field.latitude, this.field.longitude]
      const radius = +this.field.radius / 1000
      const options = {
        steps: 100,
        units: 'kilometers',
        properties: { foo: 'bar' }
      }
      return turf.circle(center, radius, options)
    },
    colorsFill() {
      const res = []
      this.steps.forEach((item) => {
        res.push({ fill: item.color })
      })
      res.push(res[res.length - 1])
      return res
    }
  },
  mounted() {
    this.initMap()
    this.getAll()
  },
  methods: {
    handleCommand(command) {
      this.addLayer(command.data)
    },
    async getPartitions() {
      const { data: { data }} = await getPartitions({ grid_type_id: this.gridTypeId })
      this.gridPartitions = data
    },
    async getAll() {
      const { data: { data }} = await getAll({ field_id: this.field.id })
      this.gridTypes = data
      this.gridType = this.gridTypes.filter((val) => {
        return val.name === 'AWC'
      })[0]
      this.gridTypeId = this.gridType.id
      this.steps = this.gridType.steps
      this.colors = this.steps.map((val) => {
        return {
          color: val.color,
          value: val.lower + '~' + val.upper
        }
      })
      const res = []
      this.steps.forEach((item, index) => {
        if (index < this.steps.length - 1) {
          res.push(item.lower)
        } else {
          res.push(item.lower)
          res.push(item.upper)
        }
      })
      this.levelV = res

      this.getPartitions()
    },
    showPointDialog() {
      this.$refs.point.show()
    },
    showDialog() {
      this.$refs.awc.show(this.gridTypeId)
    },
    addLayer(data) {
      const awc = data.map((val) => {
        const { lat, lng, awc600 } = val
        return {
          lat,
          lng,
          val: awc600
        }
      })
      this.startKriging(awc)
      this.$refs.awc.hide()
    },
    removeLayer() {
      this.show = false
      if (this.circleLayer) {
        this.map.removeLayer(this.circleLayer)
      }
      this.featureLayerGroup.clearLayers()
    },
    showOrHiddenLayer() {
      if (this.show) {
        this.removeLayer()
      } else {
        this.addLayer()
      }
    },
    initMap() {
      const googleLayers = []
      google.forEach((item) => {
        googleLayers.push(new L.TileLayer(item))
      })
      const layers = L.layerGroup(googleLayers)
      this.map = L.map('myMap', {
        center: [this.field.longitude, this.field.latitude],
        zoom: 17,
        maxZoom: 18,
        minZoom: 0,
        zoomControl: false,
        attributionControl: false,
        scrollWheelZoom: true,
        layers: [layers]
      })
      this.featureLayerGroup = new L.FeatureGroup().addTo(this.map).bringToFront()
    },
    startKriging(awc) {
      const data = average(awc.map(val => +val.val))
      const points = boundariesMerge(awc, data)

      const positionData = {
        type: 'FeatureCollection',
        features: points.map((i) => {
          return {
            type: 'Feature',
            properties: {
              value: i.val
            },
            geometry: {
              type: 'Point',
              coordinates: [+i.lng, +i.lat]
            }
          }
        })
      }
      this.showKrigingVector(positionData)
    },
    showKrigingVector(positionData) {
      // this.clearKriging()
      this.circleLayer = new L.Circle([this.field.longitude, this.field.latitude], +this.field.radius, {
        color: '#409eff',
        fillColor: '#b7ecef',
        fillOpacity: 1,
        weight: 0
      })
      this.circleLayer.addTo(this.map)
      const kriging_contours = getVectorContour(
        positionData,
        'value',
        {
          model: 'exponential',
          sigma2: 0,
          alpha: 100
        },
        this.levelV,
        this.boundaries
      )

      const features_filter = []
      kriging_contours.features.forEach((layer) => {
        let intersection = null
        try {
          intersection = turf.intersect(layer, this.circlePolygon)
        } catch (e) {
          layer = turf.buffer(layer, 0)
          intersection = turf.intersect(layer, this.circlePolygon)
        }
        if (intersection != null) {
          intersection.properties = layer.properties
          features_filter.push(intersection)
        }
      })

      L.geoJSON(features_filter, {
        style: (feature) => {
          return {
            fillColor: hotColor(feature.properties.contour_value, this.colorsFill, this.levelV),
            weight: 0,
            fillOpacity: 1
          }
        }
      }).addTo(this.featureLayerGroup)
    },
    // 清空图层
    clearKriging() {
      if (this.circleLayer) {
        this.map.removeLayer(this.circleLayer)
      }
      this.featureLayerGroup.clearLayers()
    }
  }
}
</script>

<style lang="scss" scoped>
#myMap {
  width: 96vw;
  height: 96vh;
}

.tools{
    position:absolute;
    top:24px;
    right:24px;
    z-index:999;
  }
.colors{
  top:24px;
  left:24px;
  z-index:999;
  dl{
    align-items:center;
    font-size:12px;
    dt{
      display:inline-block;
      width:100px;
      height:30px;
      line-height:30px;
      text-align:center;
    }
  }
}
</style>
